package org.pupil.rpc.protocol.codec;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import org.pupil.rpc.protocol.MsgHeader;
import org.pupil.rpc.protocol.RpcProtocol;
import org.pupil.rpc.protocol.compress.Compress;
import org.pupil.rpc.protocol.compress.CompressFactory;
import org.pupil.rpc.protocol.serialization.RpcSerialization;
import org.pupil.rpc.protocol.serialization.SerializationFactory;

/**
 * 编码器
 */
public class RpcEncoder extends MessageToByteEncoder<RpcProtocol<Object>> {
    @Override
    protected void encode(ChannelHandlerContext ctx, RpcProtocol<Object> msg, ByteBuf byteBuf) throws Exception {
        // 获取消息头
        MsgHeader header = msg.getHeader();
        byteBuf.writeShort(header.getMagic());
        byteBuf.writeByte(header.getVersion());
        byteBuf.writeByte(header.getMsgType());
        byteBuf.writeByte(header.getStatus());
        byteBuf.writeLong(header.getRequestId());
        byteBuf.writeInt(header.getSerializationLen());
        final byte[] ser = header.getSerializations();
        final String serialization = new String(ser);
        byteBuf.writeBytes(ser); // 写入序列化数组
        byteBuf.writeInt(header.getCompressLen());
        final byte[] compress = header.getCompression();
        final String compression = new String(compress);
        byteBuf.writeBytes(compress); // 写入压缩数组
        RpcSerialization rpcSerialization = SerializationFactory.get(serialization); // 获取序列化器
        byte[] data = rpcSerialization.serialize(msg.getBody());
        Compress rpcCompress = CompressFactory.get(compression); // 获取压缩器
        data = rpcCompress.compress(data);
        byteBuf.writeInt(data.length); // 写入数据长度(接收方根据数据长度读取数据内容)
        byteBuf.writeBytes(data); // 写入消息体
    }
}
